//Copyright 2010 Balazs Keri, Imre Keri
//
//This file is part of FireworksCreator.
//
//FireworksCreator is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//FireworksCreator is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with FireworksCreator.  If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _PLAYER_CONTROLLER_H
#define _PLAYER_CONTROLLER_H
//
#include <global.h>
#include <map>
#include <vector>
#include <osg/Node>
#include <osg/NodeVisitor>
#include "particlefactory.h"
#include "particlesystem.h"
#include "emitter.h"
#include "shooter.h"
#include "model/root_fwd.h"
#include "model/particletemplate_fwd.h"
#include "model/emittertemplate_fwd.h"
//
namespace osg{class Geode;}
namespace player
{
class Controller:public osg::Node
{
public:
   Controller();
   Controller(const Controller &p_copy,const osg::CopyOp &p_copyop=osg::CopyOp::SHALLOW_COPY);
   ~Controller();
   META_Node(fwc,Controller);
//
   void assign_model(const model::Root &p_root);
   void deassign_model();
   bool is_model_assigned()const;
   void play();
   void pause();
   void seek(double p_time);
   bool is_paused()const;
   double get_current_time()const;
//
   bool get_gravitation_enabled()const;
   void set_gravitation_enabled(bool p_gravitation_enabled);
   bool get_friction_enabled()const;
   void set_friction_enabled(bool p_friction_enabled);
   const osg::Vec3 &get_wind()const;
   void set_wind(const osg::Vec3 &p_wind);
   void add_particle_systems(osg::Geode *p_geode);
   ParticleSystem *particle_system_for_template(const model::ParticleTemplate *p_particle_template)const;
   ParticleFactory *particle_factory_for_template(const model::ParticleTemplate *p_particle_template)const;
   Emitter *emitter_for_template(const model::EmitterTemplate *p_emitter_template)const;
//
   void traverse(osg::NodeVisitor &nv);
   osg::BoundingSphere computeBound()const;
protected:
   struct ParticleData
   {
      ParticleFactory *factory;
      osg::ref_ptr<ParticleSystem> system;
   };
   typedef std::map<const model::ParticleTemplate*,Controller::ParticleData> ParticleDataMap;
   typedef std::map<const model::EmitterTemplate*,Emitter*> EmitterMap;
   typedef std::vector<Shooter*> ShooterVector;
   typedef std::list<Shooter*> ShooterList;
//
   ParticleDataMap particle_data;
   EmitterMap emitters;
   ShooterVector shooters;
   const model::Root *root;
   bool gravitation_enabled;
   bool friction_enabled;
//
   double current_time;
   double t0;
   int frame_number;
   ShooterVector::iterator next_shooter;
   ShooterList current_shooters;
//
   bool is_frozen;
   osg::Vec3 wind;
};
}
//
#endif
